package apibasej.basic.misc;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import apibasej.basic.config.CommonProperties;

public class UtilJAXB implements CommonProperties{

	
	public static <T> T xmlToObj(File xml, Class<T> typeObj) throws JAXBException{
		JAXBContext jaxbContext = JAXBContext.newInstance(typeObj);
		Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
		return typeObj.cast(unmarshaller.unmarshal(xml));
	}
	/* ???
	PARA ERROS COMO ESTE:
	javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.portalfiscal.inf.br/nfe", local:"retEnviNFe"). Expected elements are (none)  
	
	//http://www.javac.com.br/jc/posts/list/410.page#1472
	//http://www.javac.com.br/jc/posts/list/973.page   //<<<<<<<<<<<<<<<<<<<
	public static <T> T xmlToObj(String xml, Class<T> clazz) throws JAXBException{
		JAXBContext context = JAXBContext.newInstance(clazz);//"br.com.javac.retenvinfev2"     
        Unmarshaller unmarshaller = context.createUnmarshaller();
        try(StringReader sr = new StringReader(xml)){
            JAXBElement<T> element = (JAXBElement<T>)unmarshaller.unmarshal(new StreamSource(sr),clazz);  
            return element.getValue();   
        }
	}	
	*/

	
	public static <T> T xmlToObj(String xml, Class<T> typeObj) throws JAXBException{
		JAXBContext jaxbContext = JAXBContext.newInstance(typeObj);
		Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
		try(StringReader reader = new StringReader(xml)){
			return typeObj.cast(unmarshaller.unmarshal(reader));
		}
	}
	


	
	public static String objToXML(Object obj) throws JAXBException, IOException{
		return objToXML(obj, null);//?? ConfigManager.getPropDefaultForAll(CHARSET)
	}
	public static String objToXML(Object obj, String encoding) throws JAXBException, IOException{
		try(StringWriter writer = new StringWriter()){
			getMarshaller(obj.getClass(),encoding).marshal(obj, writer);
			writer.flush();
			return writer.toString();
		}
	}
	//gera em um arquivo
	public static void objToXML(Object obj, File f, String encoding) throws JAXBException, IOException{
		getMarshaller(obj.getClass(), encoding).marshal(obj, f);
	}

	public static <T> Marshaller getMarshaller(Class<T> c, String encoding) throws JAXBException{
		JAXBContext jaxbContext = JAXBContext.newInstance(c);
		Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
		jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		if(encoding!=null){
			jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
		}
		//jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); //??
		return jaxbMarshaller;
	}
	

}
